// com.zhu.rtda.heap.ClassMember.java
package com.zhu.rtda.heap;

import com.zhu.classfile.MemberInfo;

/**
 * ClassMember 是字段（Field）和方法（Method）的公共基类。
 * 它封装了类成员共有的基本属性，如访问标志、名称、描述符以及所属的类。
 */
public class ClassMember {
    public int accessFlags;
    public String name;
    public String descriptor;
    public InstanceKlass clazz;

    public void copyMemberInfo(MemberInfo memberInfo) {
        this.accessFlags = memberInfo.getAccessFlags();
        this.name = memberInfo.getName();
        this.descriptor = memberInfo.getDescriptor();
    }

    // ========== Getter / Setter ==========

    public int getAccessFlags() { return accessFlags; }
    public void setAccessFlags(int accessFlags) { this.accessFlags = accessFlags; }

    public String getName() { return name; }
    public void setName(String name) { this.name = name; }

    public String getDescriptor() { return descriptor; }
    public void setDescriptor(String descriptor) { this.descriptor = descriptor; }

    public InstanceKlass getClazz() { return clazz; }
    public void setClazz(InstanceKlass clazz) { this.clazz = clazz; }

    // ========== 访问标志查询 ==========

    public boolean isPublic()     { return AccessFlags.ACC_PUBLIC.isSetIn(accessFlags); }
    public boolean isPrivate()    { return AccessFlags.ACC_PRIVATE.isSetIn(accessFlags); }
    public boolean isProtected()  { return AccessFlags.ACC_PROTECTED.isSetIn(accessFlags); }
    public boolean isStatic()     { return AccessFlags.ACC_STATIC.isSetIn(accessFlags); }
    public boolean isFinal()      { return AccessFlags.ACC_FINAL.isSetIn(accessFlags); }
    public boolean isSynthetic()  { return AccessFlags.ACC_SYNTHETIC.isSetIn(accessFlags); }
    public boolean isBridge()     { return AccessFlags.ACC_BRIDGE.isSetIn(accessFlags); }
    public boolean isAbstract()   { return AccessFlags.ACC_ABSTRACT.isSetIn(accessFlags); }
    public boolean isNative()     { return AccessFlags.ACC_NATIVE.isSetIn(accessFlags); }
    public boolean isSynchronized(){ return AccessFlags.ACC_SYNCHRONIZED.isSetIn(accessFlags); }

    // ========== 访问控制 (JVMS 5.4.4) ==========

    /**
     * 判断该类成员（字段或方法）是否对指定的类 d 可访问。
     * 实现 JVM 规范 5.4.4 的访问控制规则。
     *
     * @param d 访问者类
     * @return 是否可访问
     * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-5.html#jvms-5.4.4">JVMS 5.4.4</a>
     */
    public boolean isAccessibleTo(InstanceKlass d) {
        if (this.isPublic()) {
            return true;
        }
        // 定义该成员的类
        InstanceKlass c = this.clazz;

        if (this.isProtected()) {
            // 同一个类、子类、或同一个包
            return d == c || d.isSubClassOf(c) || c.getPackageName().equals(d.getPackageName());
        }
        if (!this.isPrivate()) {
            // 包访问权限（默认权限）：同一个包
            return c.getPackageName().equals(d.getPackageName());
        }

        // private：只能被定义它的类访问
        return d == c;
    }
}